#include "controlpoint.h"
#include <QDebug>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QPainter>
#include<Eigen/Core>

bool isNear(QPoint a, QPoint b) {
    a-=b;
    return QPoint::dotProduct(a, a)<100;
}

void keepG1(QPoint d1, QPoint &d2, float len) {

    Eigen::Vector2f n(-d1.x(), -d1.y());
    n/=n.norm();
    n*=len;
    d2.setX(n.x());
    d2.setY(n.y());

}

ControlPoint::ControlPoint(QWidget *parent) : QLabel(parent)
{
    setMouseTracking(true);
    //setAttribute(Qt::WA_TransparentForMouseEvents);
    leftDir = QPoint(-1, -1);
    rightDir = QPoint(1, 1);
    leftLen = 0;
    rightLen = 0;
}

void ControlPoint::updateBox(){
    QRect rect(middle, middle);
    QPoint t[2] ={ middle + leftDir, middle +rightDir};
    for(auto p: t){
        if(p.y()< rect.top()) rect.setTop(p.y());
        if(p.y()> rect.bottom()) rect.setBottom(p.y());
        if(p.x()< rect.left()) rect.setLeft(p.x());
        if(p.x()> rect.right()) rect.setRight(p.x());
    }
    int offset = 10;
    rect.setTopLeft( rect.topLeft() - QPoint(offset, offset));
    rect.setBottomRight( rect.bottomRight() + QPoint(offset, offset));
    this->setGeometry(rect);
    update();
}

void ControlPoint::enterEvent(QEvent *event)
{
    //qDebug()<<"鼠标进入了";
}

void ControlPoint::leaveEvent(QEvent *event)
{
    //qDebug()<<"鼠标离开了";
}

void ControlPoint::mouseMoveEvent(QMouseEvent *ev)
{
    if(!drag)return;
    QString str1 = QString("鼠标移动了 drag=%1")
            .arg(drag);
    //qDebug()<<str1;
    QString str = QString("鼠标移动了 x=%1, y=%2, globalX=%3, globalY=%4" )
            .arg(ev->x()).arg(ev->y())
            .arg(ev->globalX()).arg(ev->globalY());
    //qDebug()<<str;
    auto movement = ev->globalPos()-lastPos;
        lastPos = ev->globalPos();
        if(drag==1){
            middle += movement;
        }else if(drag ==2) {
            leftDir+=movement;
            leftLen = Eigen::Vector2f(leftDir.x(), leftDir.y()).norm();
            keepG1(leftDir, rightDir, rightLen);
        }
        else if(drag == 3){
            rightDir += movement;
            rightLen = Eigen::Vector2f(rightDir.x(), rightDir.y()).norm();
            keepG1(rightDir, leftDir, leftLen);
        }

        updateBox();
        str = QString("dir  leftx=%1, lefty=%2, rightX=%3, rightY=%4" )
                .arg(leftDir.x()).arg(leftDir.y())
                .arg(rightDir.x()).arg(rightDir.y());
        //qDebug()<<str;
}

void ControlPoint::mousePressEvent(QMouseEvent *ev)
{
    if(ev->button()==Qt::MouseButton::LeftButton) {

        lastPos = ev->globalPos();
        QPoint recPos = ev->pos();
        QPoint center = middle - this->pos();

        if(isNear(center , recPos)) drag=1;
        else if(isNear(center+leftDir, recPos))drag=2;
        else if(isNear(center+rightDir, recPos))drag=3;
        else QLabel::mousePressEvent(ev);

        QString str1 = QString("鼠标按下了 drag=%1")
                .arg(drag);
        qDebug()<<str1;
    }
}

void ControlPoint::mouseReleaseEvent(QMouseEvent *ev)
{

    if(ev->button()==Qt::MouseButton::LeftButton) {
//        QString str = QString("鼠标释放了 x=%1, y=%2, globalX=%3, globalY=%4" )
//                .arg(ev->x()).arg(ev->y())
//                .arg(ev->globalX()).arg(ev->globalY());
        //qDebug()<<str;
        if(!drag)QLabel::mouseReleaseEvent(ev);
        drag=0;
        QString str1 = QString("鼠标释放了 drag=%1")
                .arg(drag);
        //qDebug()<<str1;
    }
}

bool ControlPoint::event(QEvent *e)
{
//    if(e->type()==QEvent::MouseButtonPress) {
//        QMouseEvent *ev = static_cast<QMouseEvent*>(e);
//        QString str = QString("Event 鼠标按下了 x=%1, y=%2, globalX=%3, globalY=%4" )
//                .arg(ev->x()).arg(ev->y())
//                .arg(ev->globalX()).arg(ev->globalY());
//        qDebug()<<str;
//        return true;
//    }

    return QLabel::event(e);
}

void ControlPoint::setMiddle(int x, int y){
    middle = {x, y};
    updateBox();
}

void ControlPoint::setRight(float x, float y)
{
    leftDir = QPoint(-x, -y);
    rightDir = QPoint(x, y);
    leftLen = Eigen::Vector2f(leftDir.x(), leftDir.y()).norm();
    rightLen = leftLen;
    updateBox();
}

//绘图事件
void ControlPoint::paintEvent(QPaintEvent *event){
    QLabel::paintEvent(event);
    //qDebug()<<"画画";
    QPainter painter(this);
    QPen pen;

    pen.setWidth(5);
    pen.setColor(Qt::red);
    painter.setPen(pen);
    painter.drawPoint(middle-pos());
    if(leftLen < 1 && rightLen<1) {
        return;
    }
    pen.setColor(Qt::black);
    pen.setWidth(1);
    pen.setStyle(Qt::DashLine);
    painter.setPen(pen);

    QString str1 = QString("画画 x=%1， =%2")
            .arg(middle.x()).arg(middle.y());
    //qDebug()<<str1;
    painter.drawLine(middle-pos(), middle-pos() + leftDir);
    painter.drawLine(middle-pos(), middle-pos() + rightDir);

    QPoint center[3] ={ middle-pos(), middle-pos() + leftDir, middle-pos() + rightDir};
    pen.setColor(Qt::blue);
    pen.setStyle(Qt::SolidLine);
    painter.setPen(pen);
    for(auto c:center) {
        QRect rect(c - QPoint(5, 5), QSize(10, 10));
        painter.drawRect(rect);
    }


}
